package java8.parallel.demo01;

import com.google.common.base.Stopwatch;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * @author ChangLiang
 * @date 2020/4/23
 */
public class AppTest {

    private static long measureSumPerformance(Function<Long,Long> adder, long limit) {
        long result = Long.MAX_VALUE;
        for (int i = 0; i < 10; i++) {
            Stopwatch stopwatch = Stopwatch.createStarted();
            Long apply = adder.apply(limit);
            long duration = stopwatch.elapsed(TimeUnit.MILLISECONDS);
            if (duration < result){
                result = duration;
            }
        }
        return result;
    }

    @Test
    @DisplayName("test get cpu core number")
    public void test(){
        int processorsCount = Runtime.getRuntime().availableProcessors();
        System.out.println(processorsCount);
    }

    @Test
    @DisplayName("test normal add")
    public void test2(){
        // output: 73
        long duration = measureSumPerformance(LongAdder::iterativeSum, 100_000_000);
        System.out.printf("normal add consumes: %d%n",duration);
    }

    @Test
    @DisplayName("test stream iterator using summingLong")
    public void test3(){
        // output: 816
        System.out.printf("stream iterator using summingLong: %d%n", measureSumPerformance(LongAdder::streamIterateUsingSummingLong,100_000_000));
    }

    @Test
    @DisplayName("test stream iterator using reduce")
    public void test4(){
        // output: 1202
        System.out.printf("stream iterator using reduce: %d%n", measureSumPerformance(LongAdder::sequentialSum,100_000_000));
    }

    @Test
    @DisplayName("test stream iterator using reduce by parallel")
    public void test5() {
        // output: very long
        System.out.printf("stream iterator using reduce by parallel: %d%n", measureSumPerformance(LongAdder::parallelSum,100_000_000));
    }

    @Test
    @DisplayName("test stream iterator using reduce and mapToLong by parallel")
    public void test6(){
        // output: 2311
        System.out.printf("stream iterator using reduce and mapToLong by parallel: %s%n", measureSumPerformance(LongAdder::streamIterateWithReduceByMapToLongAndParallel,100_000_000));
    }

    @Test
    @DisplayName("test LongStream using reduce by parallel")
    public void test7() {
        // output: 25
        System.out.printf("LongStream using reduce by parallel: %d%n", measureSumPerformance(LongAdder::parallelRangedSum,100_000_000));
    }

    @Test
    @DisplayName("test LongStream using reduce")
    public void test8() {
        // output: 298
        System.out.printf("LongStream using reduce: %d%n", measureSumPerformance(LongAdder::rangedSum,100_000_000));
    }


}
